#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>


// 编译时要使用 -pthread 选项
// gcc  10-ptread.c -o 10-pthread -pthread

#define   N   128 
char buf[N+1] = {0}; 
sem_t sem ; // 定义一个信号量


void *pthread_handler1(void *arg)
{
    printf("arg1=%d\n", *(int *)arg);
    printf("pthread_handler1 is running\n");
    while (1)
    {
        sem_wait(&sem); // P操作 获取信号量
        memset(buf,'O',64); 
        usleep(1000) ; // 1000us 
        memset(buf+64,'O',64); // 保证最后一个元素是0  
        usleep(1000) ; // 1000us
        sem_post(&sem); // V操作 释放信号量

    }
}
void *pthread_handler2(void *arg)
{
    printf("arg2=%d\n", *(int *)arg);
    printf("pthread_handler2 is running\n");
    while (1)
    {
        sem_wait(&sem); // P操作 获取信号量
        memset(buf,'-',64); 
        usleep(1000) ; // 1000us 
        memset(buf+64,'-',64); // 保证最后一个元素是0  
        usleep(1000) ; // 1000us 
        sem_post(&sem); // V操作 释放信号量

    }
}
void *pthread_handler3(void *arg)
{
    printf("arg3=%d\n", *(int *)arg);
    printf("pthread_handler3 is running\n");
    while (1)
    {
        sem_wait(&sem); // P操作 获取信号量
        printf("buf=%s\n",buf); 
        sem_post(&sem); // V操作 释放信号量
        sleep(1);
    }
}

int main(int argc, char const *argv[])
{
    pthread_t tid1,tid2,tid3; // thread id
    int data1 = 100,data2=200,data3=300;
    int ret , value ; 

    ret = sem_init(&sem,0,1) ; // 把信号量初始化为1 
    if(ret < 0)
    {
        perror("sem_init");
        exit(-1);
    }
    sem_getvalue(&sem,&value);
    printf("sem=%d\n",value); 

    // 创建子线程1
    ret = pthread_create(&tid1, NULL, pthread_handler1, (void *)&data1);
    if (ret != 0)
    {
        printf("pthread_create error\n");
        exit(-1);
    }

    // 创建子线程2
    ret = pthread_create(&tid2, NULL, pthread_handler2, (void *)&data2);
    if (ret != 0)
    {
        printf("pthread_create error\n");
        exit(-1);
    }

    // 创建子线程3
    ret = pthread_create(&tid3, NULL, pthread_handler3, (void *)&data3);
    if (ret != 0)
    {
        printf("pthread_create error\n");
        exit(-1);
    }

    printf("tid1=%ld\n",tid1);
    printf("tid2=%ld\n",tid2);
    printf("tid3=%ld\n",tid3);
    printf("main pthread is running\n"); 

    while(1)
    {
        sem_wait(&sem); // P操作 获取信号量
        printf("buf=%s\n",buf); 
        sem_post(&sem); // V操作 释放信号量
        sleep(1);
    }
    
    return 0;
}